{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Human_Detector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A boilerplate code, useful for beginners in OpenCV.\n",
    "I have explained the proper steps with suitable comments.\n",
    "Users are welcome to edit the code as they find suitable.\n",
    "Kindly don't attempt to change the SVM model used, as accuracy is not the key, but usability is."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import imutils\n",
    "import argparse"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "We will use HOGDescriptor, i.e. Histogram of Open Gradients with SVM already implemented in OpenCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "HOGCV = cv2.HOGDescriptor()\n",
    "HOGCV.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### detect Function\n",
    "\n",
    "This function is used for text input on the Output Screen.\n",
    "By playing with scale, varying accuracy can be obtained. This is the function which returns the frame that is then used by `humanDetector` for using the frames for detection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def detect(frame):\n",
    "    bounding_box_cordinates, weights = HOGCV.detectMultiScale(frame, winStride=(4, 4), padding=(8, 8), scale=1.03)\n",
    "\n",
    "    person = 1\n",
    "    for x, y, w, h in bounding_box_cordinates:\n",
    "        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)\n",
    "        cv2.putText(frame, f'person {person}', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)\n",
    "        person += 1\n",
    "\n",
    "    cv2.putText(frame, 'Status : Detecting ', (40, 40), cv2.FONT_HERSHEY_DUPLEX, 0.8, (255, 0, 0), 2)\n",
    "    cv2.putText(frame, f'Total Persons : {person - 1}', (40, 70), cv2.FONT_HERSHEY_DUPLEX, 0.8, (255, 0, 0), 2)\n",
    "    cv2.imshow('output', frame)\n",
    "    return frame"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### Human Detector Function\n",
    "\n",
    "This Function is simply for selecting which mode to use,\n",
    "\n",
    "- Camera\n",
    "- Image\n",
    "- Video\n",
    "\n",
    "Additionaly paths, if provided are parsed here as well."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def humanDetector(args):\n",
    "    image_path = args[\"image\"]\n",
    "    video_path = args['video']\n",
    "    if str(args[\"camera\"]) == 'true' : camera = True\n",
    "    else : camera = False\n",
    "    writer = None\n",
    "    if args['output'] is not None and image_path is None:\n",
    "        writer = cv2.VideoWriter(args['output'],cv2.VideoWriter_fourcc(*'MJPG'), 10, (600,600))\n",
    "    if camera:\n",
    "        print('[INFO] Opening Web Cam.')\n",
    "        detectByCamera(writer)\n",
    "    elif video_path is not None:\n",
    "        print('[INFO] Opening Video from path.')\n",
    "        detectByPathVideo(video_path, writer)\n",
    "    elif image_path is not None:\n",
    "        print('[INFO] Opening Image from path.')\n",
    "        detectByPathImage(image_path, args['output'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### Using Video"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def detectByPathVideo(path, writer):\n",
    "    video = cv2.VideoCapture(path)\n",
    "    check, frame = video.read()\n",
    "    if check == False:\n",
    "        print('Video Not Found')\n",
    "        return\n",
    "    print('Detecting people...')\n",
    "    while video.isOpened():\n",
    "        # check is True if reading was successful\n",
    "        check, frame = video.read()\n",
    "        if check:\n",
    "            frame = imutils.resize(frame, width=min(800, frame.shape[1]))\n",
    "            frame = detect(frame)\n",
    "\n",
    "            if writer is not None:\n",
    "                writer.write(frame)\n",
    "\n",
    "            key = cv2.waitKey(1)\n",
    "            if key == ord('q'):\n",
    "                break\n",
    "        else:\n",
    "            break\n",
    "    video.release()\n",
    "    cv2.destroyAllWindows()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### Using Camera"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def detectByCamera(writer):\n",
    "    print('Here')\n",
    "    video = cv2.VideoCapture(0)\n",
    "    print('Detecting people...')\n",
    "    while True:\n",
    "        check, frame = video.read()\n",
    "        frame = detect(frame)\n",
    "        if writer is not None:\n",
    "            writer.write(frame)\n",
    "        key = cv2.waitKey(1)\n",
    "        if key == ord('q'):\n",
    "            break\n",
    "    video.release()\n",
    "    cv2.destroyAllWindows()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using Images"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "def detectByPathImage(path, output_path):\n",
    "    cv2.namedWindow(\"output\", cv2.WINDOW_NORMAL)\n",
    "    image = cv2.imread(path)\n",
    "    image = imutils.resize(image, width=min(1800, image.shape[1]))\n",
    "    result_image = detect(image)\n",
    "    if output_path is not None:\n",
    "        cv2.imwrite(output_path, result_image)\n",
    "    cv2.waitKey(0)\n",
    "    cv2.destroyAllWindows()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Arguments"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "def argsParser():\n",
    "    arg_parse = argparse.ArgumentParser()\n",
    "    arg_parse.add_argument(\"-v\", \"--video\", default=None, help=\"path to Video File \")\n",
    "    arg_parse.add_argument(\"-i\", \"--image\", default=None, help=\"path to Image File \")\n",
    "    arg_parse.add_argument(\"-c\", \"--camera\", default=False, help=\"Set true if you want to use the camera.\")\n",
    "    arg_parse.add_argument(\"-o\", \"--output\", type=str, help=\"path to optional output video file\")\n",
    "    args = vars(arg_parse.parse_args())\n",
    "    return args"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Main Function"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "if __name__ == \"__main__\":\n",
    "    HOGCV = cv2.HOGDescriptor()\n",
    "    HOGCV.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())\n",
    "    args = argsParser()\n",
    "    humanDetector(args)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "def detectByPathImage(path, output_path):\n",
    "    cv2.namedWindow(\"output\", cv2.WINDOW_NORMAL)\n",
    "    image = cv2.imread(path)\n",
    "    image = imutils.resize(image, width=min(1800, image.shape[1]))\n",
    "    result_image = detect(image)\n",
    "    if output_path is not None:\n",
    "        cv2.imwrite(output_path, result_image)\n",
    "    cv2.waitKey(0)\n",
    "    cv2.destroyAllWindows()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Arguments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "def argsParser():\n",
    "    arg_parse = argparse.ArgumentParser()\n",
    "    arg_parse.add_argument(\"-v\", \"--video\", default=None, help=\"path to Video File \")\n",
    "    arg_parse.add_argument(\"-i\", \"--image\", default=None, help=\"path to Image File \")\n",
    "    arg_parse.add_argument(\"-c\", \"--camera\", default=False, help=\"Set true if you want to use the camera.\")\n",
    "    arg_parse.add_argument(\"-o\", \"--output\", type=str, help=\"path to optional output video file\")\n",
    "    args = vars(arg_parse.parse_args())\n",
    "    return args"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Main Function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "if __name__ == \"__main__\":\n",
    "    HOGCV = cv2.HOGDescriptor()\n",
    "    HOGCV.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())\n",
    "    args = argsParser()\n",
    "    humanDetector(args)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def detectByPathImage(path, output_path):\n",
    "    cv2.namedWindow(\"output\", cv2.WINDOW_NORMAL)\n",
    "    image = cv2.imread(path)\n",
    "    image = imutils.resize(image, width=min(1800, image.shape[1]))\n",
    "    result_image = detect(image)\n",
    "    if output_path is not None:\n",
    "        cv2.imwrite(output_path, result_image)\n",
    "    cv2.waitKey(0)\n",
    "    cv2.destroyAllWindows()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Arguments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def argsParser():\n",
    "    arg_parse = argparse.ArgumentParser()\n",
    "    arg_parse.add_argument(\"-v\", \"--video\", default=None, help=\"path to Video File \")\n",
    "    arg_parse.add_argument(\"-i\", \"--image\", default=None, help=\"path to Image File \")\n",
    "    arg_parse.add_argument(\"-c\", \"--camera\", default=False, help=\"Set true if you want to use the camera.\")\n",
    "    arg_parse.add_argument(\"-o\", \"--output\", type=str, help=\"path to optional output video file\")\n",
    "    args = vars(arg_parse.parse_args())\n",
    "    return args"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Main Function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if __name__ == \"__main__\":\n",
    "    HOGCV = cv2.HOGDescriptor()\n",
    "    HOGCV.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())\n",
    "    args = argsParser()\n",
    "    humanDetector(args)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}